/*
 *  Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package app.biz.controller;

import app.biz.service.TccActionOne;
import app.biz.service.TccActionThree;
import app.biz.service.TccActionTwo;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * The type Asset controller.
 */
@Controller
@RequestMapping
public class TCCController {

    private static final Logger logger = LoggerFactory.getLogger(TCCController.class);

    /**
     * The Port.
     */
    @Value("${server.port}")
    String port;


    @Autowired
    TccActionOne tccActionOne;
    @Autowired
    TccActionTwo tccActionTwo;
    @Autowired
    TccActionThree tccActionThree;

    /**
     * 测试提交成功
     * @param name
     * @return
     */
    @RequestMapping(value = "/tcc/success")
    @ResponseBody
    @GlobalTransactional
    public String success(String name) {
        //第一个TCC 事务参与者
        tccMock(name);
        return "success";
    }

    /**
     * 测试回滚
     * @param name
     * @return
     */
    @RequestMapping(value = "/tcc/rollback")
    @ResponseBody
    public String rollback(String name) {
        tccErrorMock(name);
        return "rollback";
    }

    /**
     * 测试回滚失败后是否重试
     * @return
     */
    @RequestMapping(value = "/tcc/retry")
    @ResponseBody
    @GlobalTransactional
    public String retry() {
        tccActionThree.prepare(null);
        throw new RuntimeException("invoke transaction rollback!");
//        return "retry";
    }

    private void tccMock(String name) {
        // 第一个TCC 事务参与者
        boolean result = tccActionOne.prepare(null, 1, name);
        if (!result) {
            throw new RuntimeException("TccAction1 failed.");
        }
        result = tccActionTwo.prepare(null, name);
        if (!result) {
            throw new RuntimeException("TccAction2 failed.");
        }
    }

    @GlobalTransactional
    private void tccErrorMock(String name) {
        tccMock(name);
        // 截止到@GlobalTransactional方法结束时，不出现任何异常才会执行COMMIT操作，否则直接回滚！
        throw new RuntimeException("transaction rollback mock!");
    }


}
